//
//  EncryptVc.m
//  Project_Demo
//
//  Created by caoxiaozhu on 2018/7/3.
//  Copyright © 2018年 caoxiaozhu. All rights reserved.
//

/*
 由于密码加密一般用于密码或者简单字符串数据加密，所以放在NSString的分类中
 */

#import "EncryptVc.h"
#import "UILabel+init.h"

@interface EncryptVc()

@property(nonatomic,strong)UITextField *inputField;
@property(nonatomic,strong)UITextView *enTextView;
@property(nonatomic,strong)UITextField *deTextField;

@property(nonatomic,strong)UIButton *actionBtn;
@property(nonatomic,strong)UIButton *dragBtn;
@property(nonatomic,assign)NSInteger flag;

@property(nonatomic,strong)UIButton *clearBtn;

@end

static NSString * const guideStr = @"请输入需要加密的文本";
static NSString * const enTitleStr = @"加密后的内容";
static NSString * const deTitleStr = @"解密后的内容";
static NSString * const enBtnStr = @"加密";
static NSString * const deBtnStr = @"解密";
static NSString * const clearBtnStr = @"清空";

@implementation EncryptVc

-(void)viewDidLoad{
    [super viewDidLoad];
    
    //设置输入UI
    [self setupUI];
    
}

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    [self.view endEditing:true];
}

#pragma mark:设置输入UI
-(void)setupUI{
    
    //下拉选择器
    _dragBtn = [UIButton createButtonWithFrame:CGRectMake(0, naviHeight+30, 300, 30) buttonType:kButtonNormal title:@"请选择加密方式" tag:4 target:self action:@selector(clickBtn:)];
    _dragBtn.centerX = self.view.centerX;
    [self.view addSubview:_dragBtn];
    
    //
    UILabel *firLabel = [UILabel labelWithStr:guideStr Frame:CGRectMake(0, naviHeight+80, 200, 30)  fontSize:FONT(18) textLine:1 textColor:Color_Black TextAlignment:0];
    firLabel.centerX = self.view.centerX;
    [self.view addSubview:firLabel];
    
    _inputField = [UITextField textFieldWithPlaceHolder:@"请输入加密值" PlaceHolderColor:nil BorderType:UITextBorderStyleRoundedRect SecureTextEntry:false Text:nil TextColor:Color_White BackgroundColor:Color_Gray KeyboardType:UIKeyboardTypeDefault];
    _inputField.frame = CGRectMake(0, firLabel.bottom+10, kScreenWidth, 30);
    [self.view addSubview:_inputField];
    
    UILabel *secLabel = [UILabel labelWithStr:enTitleStr Frame:CGRectMake(0, _inputField.bottom + 10, kScreenWidth, 30) fontSize:FONT(18) textLine:1 textColor:Color_Black TextAlignment:NSTextAlignmentCenter];
    secLabel.centerX = self.view.centerX;
    [self.view addSubview:secLabel];
    
    _enTextView  = [UITextView textViewWithStr:nil BackgroundColor:Color_Gray KeyboardType:UIKeyboardTypeDefault ScrollEnable:YES CanEditable:NO Font:FONT(18) TextAlignment:0 TextColor:Color_White];
    _enTextView.frame = CGRectMake(0, secLabel.bottom+10, kScreenWidth, 200);
    [self.view addSubview:_enTextView];
    
    UILabel *thirLabel = [UILabel labelWithStr:deTitleStr Frame:CGRectMake(0, _enTextView.bottom+10, kScreenWidth, 30) fontSize:FONT(18) textLine:1 textColor:Color_Black TextAlignment:NSTextAlignmentCenter];
    [self.view addSubview:thirLabel];
    
    _deTextField = [UITextField textFieldWithPlaceHolder:@"" PlaceHolderColor:nil BorderType:UITextBorderStyleRoundedRect SecureTextEntry:false Text:nil TextColor:Color_White BackgroundColor:Color_Gray KeyboardType:UIKeyboardTypeDefault];
    _deTextField.frame = CGRectMake(0, thirLabel.bottom+10, kScreenWidth, 30);
    _deTextField.centerX = firLabel.centerX;
    [self.view addSubview:_deTextField];
    
    NSArray *titleArr = @[@"加密",@"解密"];
    CGFloat btnX = 0;
    CGFloat margin = 30;
    CGFloat btnW =(kScreenWidth - margin) / 2;
    CGFloat btnH = 30;
    for (int i = 0 ; i<2; i++) {
        
        _actionBtn = [UIButton createButtonWithFrame: CGRectMake((btnX+ i) * (btnW +margin), _deTextField.bottom+20, btnW, btnH) buttonType:kButtonNormal title:titleArr[i] tag:100 target:self action:nil];
        
        if (i == 0) {
            
            [_actionBtn addTarget:self action:@selector(enAction:) forControlEvents:UIControlEventTouchUpInside];
        }else if(i == 1){
        
            [_actionBtn addTarget:self action:@selector(deAction:) forControlEvents:UIControlEventTouchUpInside];
        }
        
        [self.view addSubview:_actionBtn];
    }
    
    _clearBtn = [UIButton createButtonWithFrame: CGRectMake(0, _deTextField.bottom+70, kScreenWidth, 30) buttonType:kButtonNormal title:@"清空" tag:3 target:self action:@selector(clearAction:)];
    [self.view addSubview:_clearBtn];
}


-(void)clickBtn:(UIButton *)sender{
    NSLog(@"点击了按钮tag == >%ld",(long)sender.tag);
    
    NSArray *enArrs = [NSArray arrayWithObjects:@"RSA", @"DES", @"3DES", @"AES",@"MD5",@"SHA1",@"MAC", nil];
    
//    [ActionSheetStringPicker showPickerWithTitle:@"selector a color" rows:colors initialSelection:0 doneBlock:^(ActionSheetStringPicker *picker, NSInteger selectedIndex, id selectedValue) {
//        
//        NSLog(@"Picker: %@, Index: %ld, value: %@",
//              picker, selectedIndex, selectedValue);
//        
//    } cancelBlock:^(ActionSheetStringPicker *picker) {
//        NSLog(@"Block Picker Canceled");
//    } origin:sender];
    
    __weak typeof(self)weakSelf = self;
    [BRStringPickerView showStringPickerWithTitle:@"请选择你要加密的算法" dataSource:enArrs defaultSelValue:@"RSA" resultBlock:^(id selectValue) {
        
        if ([selectValue isEqualToString: @"RSA"]) {
            weakSelf.flag = 0;
        }else if ([selectValue isEqualToString:@"3DES"]){
            weakSelf.flag = 1;
        }else if ([selectValue isEqualToString:@"DES"]){
            weakSelf.flag = 2;
        }else if ([selectValue isEqualToString:@"MD5"]){
            weakSelf.flag = 3;
        }else if ([selectValue isEqualToString:@"MAC"]){
            weakSelf.flag = 4;
        }else if ([selectValue isEqualToString:@"SHA1"]){
            weakSelf.flag = 5;
        }else if ([selectValue isEqualToString:@"AES"]){
            weakSelf.flag = 6;
        }
        
        [weakSelf.dragBtn setTitle:selectValue forState:UIControlStateNormal];
//        textField.text = self.infoModel.genderStr = selectValue;
    }];
    
//    NSDictionary *propertyDict = @{ZJPickerViewPropertyCanceBtnTitleKey : @"取消",
//          ZJPickerViewPropertySureBtnTitleKey  : @"确定",
//          ZJPickerViewPropertyTipLabelTextKey  : @"提示内容",
//          ZJPickerViewPropertyTipLabelTextColorKey:[UIColor hex:@"#231F20"],
//          ZJPickerViewPropertyIsTouchBackgroundHideKey : @"Yes",
//                                   };
//    
//    
//    [ZJPickerView zj_showWithDataList:colors propertyDict:propertyDict completion:^(NSString * _Nullable selectContent) {
//        NSLog(@"ZJPickerView log tip：---> selectContent:%@", selectContent);
//        
//        
//        
//    }];
}

//加密Btn
-(void)enAction:(UIButton *)btn{
    
    switch (_flag) {
        case 0:
            NSLog(@"RSA");
            //RSA加密
            [self encrRSA:_inputField.text Mode:0];
            break;
        case 1:
            NSLog(@"3DES");
            //DES加密
            [self encr3DES:_inputField.text mode:0];
            break;
        case 2:
            NSLog(@"DES");
            //DES加密
            [self encrDES:_inputField.text mode:0];
            break;
        case 3:
            NSLog(@"MD5");
            //RSA加密
            [self encrMD5:_inputField.text];
            break;
        case 4:
            NSLog(@"MAC");
            //RSA加密
            [self encrMAC:_inputField.text];
            break;
        case 5:
            NSLog(@"MD5");
            //RSA加密
            [self encrSHA1:_inputField.text];
            break;
        case 6:
            NSLog(@"AES");
            [self encrAES:_inputField.text Mode:0];
            break;
            
        default:
            break;
    }
//    NSLog(@"加密");
}

//解密Btn
-(void)deAction:(UIButton *)btn{
//    NSLog(@"解密");
    
    switch (_flag) {
        case 0:
            NSLog(@"RSA");
            [self encrRSA:_enTextView.text Mode:1];
            break;
        case 2:
            NSLog(@"DES");
            //DES加密
            [self encrDES:_enTextView.text mode:1];
            break;
        case 6:
            NSLog(@"AES");
            [self encrAES:_enTextView.text Mode:1];
            break;
            
        default:
            break;
    }
    
}

//清除Btn
-(void)clearAction:(UIButton *)btn{
    NSLog(@"清除");
    _enTextView.text = @"";
    _deTextField.text = @"";
    _inputField.text = @"";
}


/*1、AES加密（对称加密算法）
 优点：简单、可并行计算、误差不传递
 缺点：不能隐藏明文模式（比如图像加密轮廓仍在）、主动攻击（改明文，后续内容不影响，只要误差不传递该缺点就存在）
 用途：需要并行加密的应用
 AES加密算法是密码学中的高级加密标准，该加密算法采用对称分组密码体制，密钥长度的最少支持为128、192、256，分组长度128位，算法应易于各种硬件和软件实现。这种加密算法是美国联邦政府采用的区块加密标准，这个标准用来替代原先的DES，已经被多方分析且广为全世界所使用。设计为支持128／192／256位（/32=nb)数据块大小（即分组长度）；支持128／192／256位（/32=nk)密码长度，，在10进制里，对应34×1038、62×1057、1.1×1077个密钥*/

#pragma mark - AES
-(void)encrAES:(NSString *)str Mode:(NSInteger)mode{
    
    //加密/解密
    if (mode == 0) {
        NSString *aesStr = [NSString encryptAESData:str];
        NSLog(@"aesStr===>%@",aesStr);
        _enTextView.text = aesStr;
    }else{
        NSString *decrypt = [NSString decryptAESData:_enTextView.text];
        _deTextField.text = decrypt;
    }
}


/*
 RSA加密（非对称加密）
 特点
 RSA加密算法是目前最有影响力的公钥加密算法，并且被普遍认为是目前最优秀的公钥方案之一。RSA是第一个能同时用于加密和数宇签名的算法，它能够抵抗到目前为止已知的所有密码攻击，已被ISO推荐为公钥数据加密标准。RSA加密算法基于一个十分简单的数论事实：将两个大素数相乘十分容易，但想要对其乘积进行因式分解却极其困难，因此可以将乘积公开作为加密密钥。
 算法描述：
 （1）选择一对不同的、足够大的素数p，q。
 （2）计算n=pq。
 （3）计算f(n)=(p-1)(q-1)，同时对p, q严加保密，不让任何人知道。
 （4）找一个与f(n)互质的数e（公钥指数），且1<e<f(n)。
 （5）计算d（私钥指数），使得de≡1 mod f(n)。这个公式也可以表达为d ≡e-1 mod f(n)注，≡是数论中表示同余的符号。
 （6）公钥KU=(e,n)，私钥KR=(d,n)。
 （7）加密时，先将明文变换成0至n-1的一个整数M。若明文较长，可先分割成适当的组，然后再进行交换。设密文为C，则加密过程为： C = Me（mod n）
 （8）解密过程为： M = Cd（mod n）
 
 使用RSA情况 ：客户端进行登录时 使用较多（非对称加密方式）
 在使用RSA 加密前期准备 ：
 1、需要用到.der和.p12后缀格式的文件，其中.der格式的文件存放的是公钥（Public key）用于加密，.p12格式的文件存放的是私钥（Private key）用于解密（生成的文件 在电脑磁盘中 ）
 2、 将文件导入工程
 3、 添加Security.framework框架
 4、导入.der和.p12格式的秘钥文件
 注意：一定要记住你生成的.p12文件的密码 在解密的时候需要配合这个密码来使用
 【生成教程】
 {
 生成环境是在mac系统下，使用openssl进行生成，首先打开终端，按下面这些步骤依次来做：
 
 1. 生成模长为1024bit的私钥文件private_key.pem
 
 openssl genrsa -out private_key.pem 1024
 2. 生成证书请求文件rsaCertReq.csr
 
 openssl req -new -key private_key.pem -out rsaCerReq.csr
 注意：这一步会提示输入国家、省份、mail等信息，可以根据实际情况填写，或者全部不用填写，直接全部敲回车.
 
 3. 生成证书rsaCert.crt，并设置有效时间为1年
 
 openssl x509 -req -days 3650 -in rsaCerReq.csr -signkey private_key.pem -out rsaCert.crt
 4. 生成供iOS使用的公钥文件public_key.der
 
 openssl x509 -outform der -in rsaCert.crt -out public_key.der
 5. 生成供iOS使用的私钥文件private_key.p12
 
 openssl pkcs12 -export -out private_key.p12 -inkey private_key.pem -in rsaCert.crt
 注意：这一步会提示给私钥文件设置密码，直接输入想要设置密码即可，然后敲回车，然后再验证刚才设置的密码，再次输入密码，然后敲回车，完毕！
 在解密时，private_key.p12文件需要和这里设置的密码配合使用，因此需要牢记此密码.
 
 6. 生成供Java使用的公钥rsa_public_key.pem
 
 openssl rsa -in private_key.pem -out rsa_public_key.pem -pubout
 7. 生成供Java使用的私钥pkcs8_private_key.pem
 
 openssl pkcs8 -topk8 -in private_key.pem -out pkcs8_private_key.pem -nocrypt
 
 8.找到生成的文件所在位置，将public_key.der和private_key.p12这两个文件导入工程
 
 参考资料  http://www.jianshu.com/p/74a796ec5038
 生成密钥字符串网址
 http://web.chacuo.net/netrsakeypair
 这是一个在线生成RSA秘钥的网站, 生成公钥和秘钥后, 复制出来用于测试
 }
 */
#pragma mark - RSA
-(void)encrRSA:(NSString *)str Mode:(NSInteger)mode{
    
    if (mode == 0) {
        NSString *public_key_path = bundleFileName(@"public_key.der");
        //    1.   使用.der的公钥加密@"public_key.der
        NSString *encryptString = [NSString encryptString:str publicKeyWithContentsOfFile:public_key_path];
        NSLog(@"RSAStr===>%@",encryptString);
        _enTextView.text = encryptString;
    }else{
        NSString *private_key_path = [[NSBundle mainBundle] pathForResource:@"private_key.p12" ofType:nil];
        NSString *decrypt = [NSString decryptString:_enTextView.text privateKeyWithContentsOfFile:private_key_path password:@"987654321"];
        _deTextField.text = decrypt;
    }
}


/**
 MD5加密
 MD5的作用是让大容量信息在用数字签名软件签署私人密钥前被"压缩"成一种保密的格式（就是把一个任意长度的字节串变换成一定长的十六进制数字串）。
 全写： Message Digest Algorithm MD5（中文名为消息摘要算法第五版）
 输出： 128bit
 特点：
 1、压缩性：任意长度的数据，算出的MD5值长度都是固定的。
 2、容易计算：从原数据计算出MD5值很容易。
 3、抗修改性：对原数据进行任何改动，哪怕只修改1个字节，所得到的MD5值都有很大区别。
 4、弱抗碰撞：已知原数据和其MD5值，想找到一个具有相同MD5值的数据（即伪造数据）是非常困难的。
 5、强抗碰撞：想找到两个不同的数据，使它们具有相同的MD5值，是非常困难的。
 缺陷：Md5一度被认为十分靠谱。2004年8月17日的美国加州圣巴巴拉的国际密码学会议（Crypto’2004）上，来自中国山东大学的王小云教授做了破译MD5、HAVAL-128、 MD4和RIPEMD算法的报告，公布了MD系列算法的破解结果。2009年，冯登国、谢涛二人利用差分攻击，将MD5的碰撞算法复杂度从王小云的2^42进一步降低到2^21，极端情况下甚至可以降低至2^10。仅仅2^21的复杂度意味着即便是在2008年的计算机上，也只要几秒便可以找到一对碰撞。Md5已老， 在安全性要求较高的场合，不建议使用。
 
 */
#pragma mark - MD5
-(void)encrMD5:(NSString *)str{
    NSLog(@"MD5");
    NSString *md5Str = [_inputField.text md5WithString];
    _enTextView.text = md5Str;
}

/*
 sha1（安全[哈希算法]）只是叫做一种算法，用于检验数据完整性
 全名： 安全哈希算法（Secure Hash Algorithm）输出： 160bit
 与Md5比较
 相同点：
 因为二者均由MD4导出，SHA-1和MD5彼此很相似。相应的，他们的强度和其他特性也是相似。
 不同点：
 1. 对强行攻击的安全性：最显著和最重要的区别是SHA-1摘要比MD5摘要长32 位。使用强行技术，产生任何一个报文使其摘要等于给定报摘要的难度对MD5是2^128数量级的操作，而对SHA-1则是2^160数量级的操作。这样，SHA-1对强行攻击有更大的强度。
 2. 对密码分析的安全性：由于MD5的设计，易受密码分析的攻击，SHA-1显得不易受这样的攻击。
 3. 速度：在相同的硬件上，SHA-1的运行速度比MD5慢。
 */

#pragma mark - SHA1
-(void)encrSHA1:(NSString*)str{
    NSString *encrypt = [NSString Sha256:str];
    _enTextView.text = encrypt;
}

/**
 消息摘要算法
 我们通常在遇到的时候会看到“HMAC”字眼，mac（Message Authentication Code，消息认证码算法）是含有密钥散列函数算法，兼容了MD和SHA算法的特性，并在此基础上加上了密钥。因此MAC算法也经常被称作HMAC算法。
 */
#pragma mark - MAC
-(void)encrMAC :(NSString *)str{
    NSString *encrypt = [NSString Hmac:str withKey:PGGkey];
    _enTextView.text = encrypt;
}

#pragma mark - DES
-(void)encrDES :(NSString *)str mode:(NSInteger)mode{
    if (mode == 0) {
        NSString *encrypt = [NSString encryptUseDES:str];
        _enTextView.text = encrypt;
    }else{
        NSString *decrypt = [NSString decryptUseDES:str];
        _deTextField.text = decrypt;
    }
}

#pragma mark - 3DES
-(void)encr3DES:(NSString *)str mode:(NSInteger)mode{
    if (mode == 0) {
        NSString *encrypt = [str enTriple3DESWithKey:TkEY Iv:TIV];
        _enTextView.text = encrypt;
        
    }else{
        
    }
}

@end
